package com.aiden.app.common.http

import com.aiden.app.common.http.config.HttpGlobalConfig
import com.aiden.app.common.util.LogUtils
import com.google.gson.Gson
import okhttp3.*
import retrofit2.CallAdapter
import retrofit2.Converter
import retrofit2.Retrofit
import java.io.File
import java.security.GeneralSecurityException
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

class NetWork private constructor() {

    private var okHttpBuilder: OkHttpClient.Builder = OkHttpClient.Builder()
    private var retrofitBuilder: Retrofit.Builder = Retrofit.Builder()
    private lateinit var retrofit: Retrofit
    val gson = Gson()

    companion object {
        val INSTANCE = NetWork()
    }

    fun <T> getService(clazz: Class<T>): T = retrofit.create(clazz)

    fun connectTimeout(timeout: Long, unit: TimeUnit) {
        okHttpBuilder.connectTimeout(timeout, unit)
    }

    fun writeTimeout(timeout: Long, unit: TimeUnit) {
        okHttpBuilder.writeTimeout(timeout, unit)
    }

    fun readTimeout(timeout: Long, unit: TimeUnit) {
        okHttpBuilder.readTimeout(timeout, unit)
    }

    fun interceptor(interceptor: Interceptor) {
        okHttpBuilder.addInterceptor(interceptor)
    }

    fun networkInterceptor(interceptor: Interceptor) {
        okHttpBuilder.addNetworkInterceptor(interceptor)
    }

    fun cache(cacheDirectory: File, size: Long) {
        val cache = Cache(cacheDirectory, size)
        okHttpBuilder.cache(cache)
    }

    fun connectionPool(connectionPool: ConnectionPool) {
        okHttpBuilder.connectionPool(connectionPool)
    }

    fun cookieJar(cookieJar: CookieJar) {
        okHttpBuilder.cookieJar(cookieJar)
    }

    fun convertFactory(factory: Converter.Factory) {
        retrofitBuilder.addConverterFactory(factory)
    }

    fun callAdapterFactory(factory: CallAdapter.Factory) {
        retrofitBuilder.addCallAdapterFactory(factory)
    }

    fun getSSLContext(): SSLSocketFactory? {
        try {
            val sSLContext = SSLContext.getInstance("TLS")
            sSLContext.init(null, arrayOf<TrustManager>(
                    object : X509TrustManager {
                        @Throws(CertificateException::class)
                        override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {

                        }

                        @Throws(CertificateException::class)
                        override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {
                        }

                        @Throws(CertificateException::class)
                        override fun getAcceptedIssuers(): Array<X509Certificate> {
                            return arrayOf()
                        }
                    }
            ), null)
            return sSLContext.socketFactory
        } catch (e: GeneralSecurityException) {
            LogUtils.e(HttpGlobalConfig.HTTP_LOG_TAG, e.message!!)
        }
        return null
    }

    fun build(baseUrl: String) {
        val sslSocketFactory = getSSLContext()
        if (sslSocketFactory != null) {
            okHttpBuilder.sslSocketFactory(sslSocketFactory)
        }
        retrofit = retrofitBuilder
                .client(okHttpBuilder.build())
//                .client(RetrofitUrlManager.getInstance().with(okHttpBuilder).build()) // 动态修改baseUrl
                .baseUrl(baseUrl)
                .build()
    }
}